package com.huawei.fakedouyin.video;

import android.content.Context;
import android.content.pm.ActivityInfo;
import android.graphics.Color;
import android.graphics.SurfaceTexture;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Build;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.Surface;
import android.view.TextureView;
import android.view.ViewGroup;
import android.widget.FrameLayout;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.huawei.fakedouyin.util.LogUtil;
import com.huawei.fakedouyin.util.LogUtilKt;

import java.io.IOException;
import java.util.Map;

/**
 * 视频播放器 界面和控制
 */

public class TourVideoPlayer extends FrameLayout implements IVideoPlayer,
        TextureView.SurfaceTextureListener,
        MediaPlayer.OnPreparedListener,
        MediaPlayer.OnVideoSizeChangedListener,
        MediaPlayer.OnCompletionListener,
        MediaPlayer.OnErrorListener,
        MediaPlayer.OnBufferingUpdateListener,
        MediaPlayer.OnInfoListener {
    public static final int STATE_ERROR = -1;               //播放错误
    public static final int STATE_IDLE = 0;                 //播放未开始
    public static final int STATE_PREPARING = 1;            //播放准备中
    public static final int STATE_PREPARED = 2;             //播放准备就绪
    public static final int STATE_PLAYING = 3;              //正在播放
    public static final int STATE_PAUSED = 4;               //暂停播放
    public static final int STATE_BUFFERING_PLAYING = 5;    //正在缓冲
    public static final int STATE_BUFFERING_PAUSED = 6;     //正在缓冲 播放器暂时
    public static final int STATE_COMPLETED = 7;            //播放完成
    public static final int STATE_NOTE_4G = 8;              //提示4G
    public static final int STATE_NOTE_DISCONNECT = 9;      //提示断网

    public static final int MODE_NORMAL = 10;               //普通模式
    public static final int MODE_FULL_SCREEN = 11;          //全屏模式
    public static final int MODE_TINY_WINDOW = 13;          //小窗口模式

    public enum NetworkStatus {
        CONNECTED_WIFI,
        CONNECTED_4G,
        NOT_CONNECTED
    }

    private int mCurrentState = STATE_IDLE;                     //播放状态(暂停 开始...)
    private int mCurrentMode = MODE_NORMAL;                     //播放模式(全屏 小屏...)

    private Context mContext;
    private AudioManager mAudioManager;
    private MediaPlayer mMediaPlayer;
    private FrameLayout mContainer;
    private TourTextureView mTextureView;
    private Surface mSurface;
    private String mUrl;
    private Map<String, String> mHeaders;
    //   private IVideoController mController;
    private int mBufferPercentage;
    private SurfaceTexture mSurfaceTexture;
    private boolean continueFromLastPosition = false;
    private int skipToPosition;
    public static boolean allow4GFlag = false;
    OnPlayStatusChange onPlayStatusChange;

    private int pausePosition = 0;

    public TourVideoPlayer(@NonNull Context context) {
        this(context, null);
    }

    public TourVideoPlayer(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
        allow4GFlag = true;
        init();
    }

    private void init() {
        mContainer = new FrameLayout(mContext);
        mContainer.setBackgroundColor(Color.BLACK);
        LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        this.addView(mContainer, params);
    }

    /**
     * 设置播放链接
     * @param url
     * @param headers
     */
    @Override
    public void setUp(String url, Map<String, String> headers) {
        mUrl = url;
        mHeaders = headers;
    }


    @Override
    public void continueFromLastPosition(boolean continueFromLastPosition) {
        this.continueFromLastPosition = continueFromLastPosition;
    }

    /**
     * 开始播放
     */
    @Override
    public void start() {
        if (mCurrentState == STATE_IDLE) {
            //初始化播放器参数
            initAudioManager();
            initMediaPlayer();
            initTextureView();
            addTextureView();
        }
    }

    /**
     * 跳进度播放
     * @param pos
     */
    @Override
    public void start(int pos) {
        skipToPosition = pos;
        start();
    }

    /**
     * 重新播放
     */
    @Override
    public void restart() {
        //先判断状态 暂停时恢复
        if (mCurrentState == STATE_PAUSED) {
            if (mMediaPlayer == null) {
                mCurrentState = STATE_IDLE;
                start();
            } else {
                mMediaPlayer.start();
                mCurrentState = STATE_PLAYING;
                notifityChange(mCurrentState);
            }
        } else if (mCurrentState == STATE_COMPLETED || mCurrentState == STATE_ERROR) {
            //播放完成 重新播放
            mMediaPlayer.reset();
            openMediaPlayer();
        } else if (mCurrentState == STATE_IDLE) {
            //播放
            start();
        } else {
        }
    }

    @Override
    public void pause() {
        //暂停播放
        if (mCurrentState == STATE_PLAYING) {
            mMediaPlayer.pause();
            this.pausePosition = getCurrentPosition();
            mCurrentState = STATE_PAUSED;
            notifityChange(mCurrentState);
        }
    }

    /**
     * 跳进度
     * @param pos
     */
    @Override
    public void seekTo(int pos) {
        if (mMediaPlayer != null) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                //精准跳进度
                mMediaPlayer.seekTo(pos, MediaPlayer.SEEK_CLOSEST);
            } else {
                //跳到最近的关键帧 进度会不准确
                mMediaPlayer.seekTo(pos);

            }
        }
    }

    @Override
    public boolean isIdle() {
        return mCurrentState == STATE_IDLE;
    }

    @Override
    public boolean isPreparing() {
        return mCurrentState == STATE_PREPARING;
    }

    @Override
    public boolean isPrepared() {
        return mCurrentState == STATE_PREPARED;
    }

    @Override
    public boolean isBufferingPlaying() {
        return mCurrentState == STATE_BUFFERING_PLAYING;
    }

    @Override
    public boolean isBufferingPaused() {
        return mCurrentState == STATE_BUFFERING_PAUSED;
    }

    @Override
    public boolean isPlaying() {
        return mCurrentState == STATE_PLAYING;
    }

    @Override
    public boolean isPaused() {
        return mCurrentState == STATE_PAUSED;
    }

    @Override
    public boolean isError() {
        return mCurrentState == STATE_ERROR;
    }

    @Override
    public boolean isCompleted() {
        return mCurrentState == STATE_COMPLETED;
    }

    @Override
    public boolean isFullScreen() {
        return mCurrentMode == MODE_FULL_SCREEN;
    }

    @Override
    public boolean isTinyWindow() {
        return mCurrentMode == MODE_TINY_WINDOW;
    }

    @Override
    public boolean isNormal() {
        return mCurrentMode == MODE_NORMAL;
    }

    @Override
    public int getDuration() {
        return mMediaPlayer != null ? mMediaPlayer.getDuration() : 0;
    }

    /**
     * 获取当前播放进度
     * @return
     */
    @Override
    public int getCurrentPosition() {
        int currentPosition = mMediaPlayer != null ? mMediaPlayer.getCurrentPosition() : 0;
        return currentPosition;
    }

    @Override
    public int getPlayPercentage() {
        long position = getCurrentPosition();
        long duration = getDuration();
        try {
            int progress = (int) (100f * position / duration);
            return progress;
        } catch (Exception e) {
            e.printStackTrace();
            return -1;
        }
    }

    @Override
    public int getBufferPercentage() {
        return mBufferPercentage;
    }

    //全屏，将mContainer从当前容器移除，添加到android.R.content中。
    @Override
    public void enterFullScreen() {
        if (mCurrentMode == MODE_FULL_SCREEN) return;

        // 隐藏ActionBar、状态栏，并横屏
        TourVideoUtil.hideActionBar(mContext);
        TourVideoUtil.scanForActivity(mContext)
                .setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

        new Handler().post(new Runnable() {
            @Override
            public void run() {
                ViewGroup contentView = (ViewGroup) TourVideoUtil.scanForActivity(mContext)
                        .findViewById(android.R.id.content);
                if (mCurrentMode == MODE_TINY_WINDOW) {
                    contentView.removeView(mContainer);
                } else {
                    TourVideoPlayer.this.removeView(mContainer);
                }
                LayoutParams params = new LayoutParams(
                        ViewGroup.LayoutParams.MATCH_PARENT,
                        ViewGroup.LayoutParams.MATCH_PARENT);
                contentView.addView(mContainer, params);
            }
        });

        mCurrentMode = MODE_FULL_SCREEN;
        //  mController.onPlayModeChanged(mCurrentMode);
    }

    /**
     * 初始化音频
     */
    private void initAudioManager() {
        if (mAudioManager == null) {
            mAudioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
            mAudioManager.requestAudioFocus(null, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
        }
    }

    /**
     * 初始化播放器
     */
    private void initMediaPlayer() {
        if (mMediaPlayer == null) {
            mMediaPlayer = new MediaPlayer();
            mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
        }
    }

    /**
     * 初始化textureView
     */
    private void initTextureView() {
        if (mTextureView == null) {
            mTextureView = new TourTextureView(mContext);
            mTextureView.setSurfaceTextureListener(this);//此时回调onSurfaceTextureAvailable
        }
    }

    /**
     * 添加textureView
     */
    private void addTextureView() {
        mContainer.removeView(mTextureView);
        LayoutParams params = new LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT,
                Gravity.CENTER);
        mContainer.addView(mTextureView, 0, params);
    }

    @Override
    public boolean exitFullScreen() {

        return false;
    }

    @Override
    public void enterTinyWindow() {

    }

    @Override
    public boolean exitTinyWindow() {
        if (mCurrentMode == MODE_TINY_WINDOW) {
            new Handler().post(new Runnable() {
                @Override
                public void run() {
                    ViewGroup contentView = (ViewGroup) TourVideoUtil.scanForActivity(mContext)
                            .findViewById(android.R.id.content);
                    contentView.removeView(mContainer);
                    LayoutParams params = new LayoutParams(
                            ViewGroup.LayoutParams.MATCH_PARENT,
                            ViewGroup.LayoutParams.MATCH_PARENT);
                    TourVideoPlayer.this.addView(mContainer, params);
                }
            });

            mCurrentMode = MODE_NORMAL;
            // mController.onPlayModeChanged(mCurrentMode);
            return true;
        }
        return false;
    }

    @Override
    public void release() {

        mCurrentMode = MODE_NORMAL;

        // 释放播放器
        releasePlayer();

        Runtime.getRuntime().gc();
    }

    private void releasePlayer() {
        if (mAudioManager != null) {
            mAudioManager.abandonAudioFocus(null);
            mAudioManager = null;
        }
        if (mMediaPlayer != null) {
            mMediaPlayer.release();
            mMediaPlayer = null;
        }
        mContainer.removeView(mTextureView);
        if (mSurface != null) {
            mSurface.release();
            mSurface = null;
        }
        if (mSurfaceTexture != null) {
            mSurfaceTexture.release();
            mSurfaceTexture = null;
        }
        mCurrentState = STATE_IDLE;
    }

    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i1) {
        if (mSurfaceTexture == null) {
            mSurfaceTexture = surfaceTexture;
            openMediaPlayer();
        } else {
            mTextureView.setSurfaceTexture(mSurfaceTexture);
        }
    }

    private void openMediaPlayer() {
        // 屏幕常亮
        mContainer.setKeepScreenOn(true);
        // 设置监听
        mMediaPlayer.setOnPreparedListener(this);
        mMediaPlayer.setOnVideoSizeChangedListener(this);
        mMediaPlayer.setOnCompletionListener(this);
        mMediaPlayer.setOnErrorListener(this);
        mMediaPlayer.setOnInfoListener(this);
        mMediaPlayer.setOnBufferingUpdateListener(this);

        // 设置dataSource
        try {
            mMediaPlayer.setDataSource(mUrl);
            if (mSurface == null) {
                mSurface = new Surface(mSurfaceTexture);
            }
            mMediaPlayer.setSurface(mSurface);
            mMediaPlayer.prepareAsync();
            mCurrentState = STATE_PREPARING;
            notifityChange(mCurrentState);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i1) {

    }

    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
        return mSurfaceTexture == null;
    }

    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {

    }


    //setOnPreparedListener
    @Override
    public void onPrepared(MediaPlayer mp) {
        mCurrentState = STATE_PREPARED;
        notifityChange(mCurrentState);
        mp.start();

        // 跳到指定位置播放
        if (skipToPosition != 0) {

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                mp.seekTo(skipToPosition, MediaPlayer.SEEK_CLOSEST);
            } else {
                mp.seekTo(skipToPosition);
            }
        }
    }

    @Override
    public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
        mTextureView.adaptVideoSize(width, height);
    }

    @Override
    public void onCompletion(MediaPlayer mp) {
        pausePosition = 0;
        mCurrentState = STATE_COMPLETED;
        notifityChange(mCurrentState);
        // 清除屏幕常亮
        mContainer.setKeepScreenOn(false);
    }

    @Override
    public boolean onError(MediaPlayer mp, int what, int extra) {
        LogUtilKt.logDebug("播放失败：what:" + what);
        // 直播流播放时去调用mediaPlayer.getDuration会导致-38和-2147483648错误，忽略该错误
        if (what != -38 && what != -2147483648 && extra != -38 && extra != -2147483648) {
            mCurrentState = STATE_ERROR;
            notifityChange(mCurrentState);
        }
        return true;
    }

    @Override
    public void onBufferingUpdate(MediaPlayer mp, int percent) {
        mBufferPercentage = percent;
    }

    @Override
    public boolean onInfo(MediaPlayer mp, int what, int extra) {
        if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START) {
            // 播放器渲染第一帧
            mCurrentState = STATE_PLAYING;
            notifityChange(mCurrentState);
        }
        return true;
    }

    public interface OnPlayStatusChange {
        void onPlayChange(int status);
    }

    /**
     * 播放器状态变化的通知
     * @param status
     */
    private void notifityChange(int status) {
        if (this.onPlayStatusChange != null) {
            this.onPlayStatusChange.onPlayChange(status);
        }
    }

    public void setOnPlayChangeListener(OnPlayStatusChange onPlayChangeListener) {
        this.onPlayStatusChange = onPlayChangeListener;

    }
}
